package cn.jbolt.ai.app.service.impl;


import cn.hutool.core.util.StrUtil;
import cn.jbolt.ai.app.config.AppConfigConstant;
import cn.jbolt.ai.core.AIPrompts;
import cn.jbolt.util.JSONUtil;
import cn.jbolt.ai.app.dao.AiAppNodeMapper;
import cn.jbolt.ai.app.entity.AiAppNode;
import cn.jbolt.ai.app.service.AiAppConfigService;
import cn.jbolt.ai.app.service.AiAppNodeService;
import cn.jbolt.ai.core.chain.node.InnerNodeType;
import cn.jbolt.util.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jboltai.event.chain.ChainNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AiAppNodeServiceImpl extends ServiceImpl<AiAppNodeMapper, AiAppNode> implements AiAppNodeService {
    private static final Logger logger = LoggerFactory.getLogger(AiAppNodeServiceImpl.class);
    @Autowired
    private AiAppConfigService aiAppConfigService;
    @Override
    public Result<List<AiAppNode>> getNodesByAppId(Long appId) {
        List<AiAppNode> nodes = this.list(new QueryWrapper<AiAppNode>().eq("app_id", appId));
        if (nodes != null) {
            return Result.success(nodes);
        } else {
            return Result.error("节点不存在");
        }
    }

    @Override
    public Result listByPage(Integer page, Integer pageSize) {
        Page<AiAppNode> pageResult = page(new Page<>(page, pageSize));
        return Result.success(pageResult);
    }

    @Override
    public Result add(AiAppNode node) {
        boolean save = save(node);
        if (save) {
            return Result.success(node);
        } else {
            return Result.error("添加失败");
        }
    }

    @Override
    public Result update(AiAppNode node) {
        boolean update = updateById(node);
        if (update) {
            return Result.success(node);
        } else {
            return Result.error("更新失败");
        }
    }

    @Override
    public Result delete(Long id) {
        boolean delete = removeById(id);
        if (delete) {
            return Result.success();
        } else {
            return Result.error("删除失败");
        }
    }

    @Override
    public Result addNodeAfters(Long id, String caseName, Long afterId) {
        AiAppNode nodeDb = getById(id);
        if (nodeDb != null) {
             try {
                 if (nodeDb.getAfters() == null|| StrUtil.isEmpty(nodeDb.getAfters())) {//之前没有节点
                     String[] array = new String[] {afterId.toString()};
                     ObjectNode config = JSONUtil.createObjectNode().putPOJO(caseName, array);
                     nodeDb.setAfters(config.toString());
                 } else {//有节点
                     //把afters变成object对象
                     ObjectNode config = JSONUtil.toJsonObject(nodeDb.getAfters());
                     //获取caseName,这是一个存放数组的
                     ArrayNode caseConfig = (ArrayNode) config.get(caseName);
                     // 如果你需要将其作为 List<String> 来处理
                     if (caseConfig == null) {
                         config.putPOJO(caseName, new Long[]{afterId});
                     } else {
                         for (JsonNode jsonNode : caseConfig) {
                             if (jsonNode.asText().equals(afterId.toString())) {
                                 return Result.error("该节点已经存在");
                             }
                         }

                         caseConfig.add(afterId);
                     }
                     nodeDb.setAfters(config.toString());

                 }
             }catch (Exception e){
                 e.printStackTrace();
                 logger.error("更新失败,afters转换格式异常,原因:{}", e.getMessage());
                 return Result.error("更新失败,afters转换格式异常");
             }
            if (updateById(nodeDb)) {
                return Result.success();
            } else {
                return Result.error("更新失败");
            }
        }
        return Result.error("未找到节点");
    }

    @Override
    public Result initAppNodes(Long appId) {
        //先创建5个节点
        List<AiAppNode> nodeList = new ArrayList<>();
        AiAppNode node1 = new AiAppNode();
        node1.setType(InnerNodeType.FUNC_CALL);
        node1.setAppId(appId);
        nodeList.add(node1);
        AiAppNode node2 = new AiAppNode();
        node2.setType(InnerNodeType.CHAT);
        node2.setAppId(appId);
        nodeList.add(node2);
        AiAppNode node3 = new AiAppNode();
        node3.setType(InnerNodeType.KLB_SEARCH);
        node3.setAppId(appId);
        nodeList.add(node3);
        AiAppNode node4 = new AiAppNode();
        node4.setType(InnerNodeType.CHAT_WITH_KLB);
        node4.setAppId(appId);
        nodeList.add(node4);
        AiAppNode node5 = new AiAppNode();
        node5.setType(InnerNodeType.CHAT);
        node5.setAppId(appId);
        nodeList.add(node5);

        saveBatch(nodeList);
        //添加4个节点的关联关系
        Result result = addNodeAfters(node1.getId(), ChainNode.AFTER_KEY_SUCCESS, node2.getId());
        if (result.isError())  return result;
        result = addNodeAfters(node1.getId(), ChainNode.AFTER_KEY_FAIL, node3.getId());
        if (result.isError())  return result;
        result = addNodeAfters(node3.getId(), ChainNode.AFTER_KEY_SUCCESS, node4.getId());
        if (result.isError())  return result;
        result = addNodeAfters(node3.getId(), ChainNode.AFTER_KEY_FAIL, node5.getId());
        if (result.isError())  return result;

        initChatWithFuncNodeConfig(node2.getId());

        return Result.success();
    }


    /**
     * 初始化chatwithfunc call result节点的配置
     * @param nodeId
     */
    private void initChatWithFuncNodeConfig(Long nodeId) {
        ObjectNode node = JSONUtil.createObjectNode();
        node.put(AppConfigConstant.CONFIG_KEY_PROMPT_TPL, AIPrompts.CHAT_WITH_FUNC_RESULT);
        aiAppConfigService.add(AppConfigConstant.LINK_TYPE_NODE, nodeId,
                AppConfigConstant.CONFIG_TYPE_LLM, node);
    }


    @Override
    @Transactional
    public Result delAllNodeByAppId(Long appId) {
        //找到所有的节点
        QueryWrapper<AiAppNode> queryWrapper = new QueryWrapper<AiAppNode>().eq("app_id", appId);
        List<AiAppNode> nodes = list(queryWrapper);
        if (nodes != null) {
            //找到所有节点的id并返回一个node的id数组
            List<Long> nodeIds = nodes.stream().map(AiAppNode::getId).collect(Collectors.toList());
            Result result = aiAppConfigService.deleteAllConfigByLinkType(AppConfigConstant.LINK_TYPE_NODE, nodeIds);
            if (result.isError()) {
                return Result.error("删除节点配置失败");
            }
            //移除所有的node
            boolean b = removeByIds(nodeIds);
            if (!b) {
               return Result.error("删除节点失败");
            }
        }
        return Result.success();
    }



}
